/* 327 */
/***/
(function(module, exports, __webpack_require__) {

  "use strict";


  Object.defineProperty(exports, "__esModule", {
    value: true
  });

  var _toConsumableArray2 = __webpack_require__(8);

  var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

  var _getPrototypeOf = __webpack_require__(3);

  var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

  var _classCallCheck2 = __webpack_require__(0);

  var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

  var _createClass2 = __webpack_require__(1);

  var _createClass3 = _interopRequireDefault(_createClass2);

  var _possibleConstructorReturn2 = __webpack_require__(4);

  var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

  var _inherits2 = __webpack_require__(5);

  var _inherits3 = _interopRequireDefault(_inherits2);

  var _mobx = __webpack_require__(2);

  var _bind = __webpack_require__(10);

  var _bind2 = _interopRequireDefault(_bind);

  var _track = __webpack_require__(42);

  var _track2 = _interopRequireDefault(_track);

  var _XbsjBase = __webpack_require__(7);

  var _XbsjBase2 = _interopRequireDefault(_XbsjBase);

  var _XbsjCzmObj2 = __webpack_require__(11);

  var _XbsjCzmObj3 = _interopRequireDefault(_XbsjCzmObj2);

  var _XbsjObject = __webpack_require__(9);

  var _XbsjObject2 = _interopRequireDefault(_XbsjObject);

  var _registerInteractionProperty = __webpack_require__(15);

  var _kriging = __webpack_require__(328);

  var _kriging2 = _interopRequireDefault(_kriging);

  function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
      default: obj
    };
  }

  var g_ctx = void 0;

  /**
   * 获得调色板
   * @param {Array} gradient 颜色表，形式如: [[0, 'green'], [0.2, 'blue'], [0.6, 'yellow'], [1.0, 'red']]
   * @param {Uint8ClampedArray} result 必须含有256个元素 
   */
  function getColorPalette(gradient, result) {
    if (result) {
      if (!result instanceof Uint8ClampedArray) {
        throw new Error('result类型不对！');
      }

      if (result.length !== 256 * 4) {
        throw new Error('result的数组长度不对，必须为256！');
      }
    }

    if (!g_ctx) {
      var paletteCanvas = document.createElement('canvas');
      var paletteCtx = paletteCanvas.getContext('2d');
      paletteCanvas.width = 256;
      paletteCanvas.height = 1;
      g_ctx = paletteCtx;
    }

    var lg = g_ctx.createLinearGradient(0, 0, 256, 1);
    gradient.forEach(function(e) {
      lg.addColorStop(e[0], e[1]);
    });

    g_ctx.clearRect(0, 0, 256, 1);
    g_ctx.fillStyle = lg;
    g_ctx.fillRect(0, 0, 256, 1);

    var data = g_ctx.getImageData(0, 0, 256, 1).data;

    if (!result) {
      result = new Uint8ClampedArray(data);
    } else {
      data.forEach(function(e, i) {
        return result[i] = e;
      });
    }

    return result;
  };

  function getColorFromColorPalette(ratio, palette, result) {
    // const value = element.value < min ? min : (element.value > max ? max : element.value);
    // const offset = (255 * (value - min) / (max - min)) | 0; // 256会导致1.0的值错误
    var min = 0,
      max = 1;

    ratio = ratio < min ? min : ratio > max ? max : ratio;
    var offset = 255 * ratio | 0;

    var red = palette[offset * 4];
    var green = palette[offset * 4 + 1];
    var blue = palette[offset * 4 + 2];
    var alpha = palette[offset * 4 + 3];

    if (!result) {
      result = [255, 255, 255, 255];
    }

    result[0] = red;
    result[1] = green;
    result[2] = blue;
    result[3] = alpha;

    return result;
  }

  var setImageDataFunc = void 0;

  /**
   * 热力图
   * @memberof Obj
   * @class
   * @extends XbsjCzmObj
   */

  var HeatMap = function(_XbsjCzmObj) {
    (0, _inherits3.default)(HeatMap, _XbsjCzmObj);

    function HeatMap(earth, guid) {
      (0, _classCallCheck3.default)(this, HeatMap);

      var _this = (0, _possibleConstructorReturn3.default)(this, (HeatMap.__proto__ || (0, _getPrototypeOf2
        .default)(HeatMap)).call(this, earth, guid));

      _this.disposers.push((0, _bind2.default)(_this, 'enabled', _this, 'show'));

      _XbsjBase2.default.registerPosition(_this);
      // 检测位置编辑状态 // positionEditing
      _this.disposers.push((0, _registerInteractionProperty.registerPositionEditing)(_this._earth, _this, {
        positionEditingProperty: 'editing'
      }));
      _this.disposers.push((0, _registerInteractionProperty.registerPositionPicking)(_this._earth, _this, {
        positionPickingProperty: 'creating'
      }));

      _this._customGroundRectangle = new XE.Obj.CustomGroundRectangle(earth);
      _this.disposers.push((0, _track2.default)(_this._customGroundRectangle, 'show', _this, 'show'));
      _this.disposers.push(function() {
        _this._customGroundRectangle = _this._customGroundRectangle && _this._customGroundRectangle
          .destroy();
      });

      var updateGroundRectangle = function updateGroundRectangle() {
        var cgr = _this._customGroundRectangle;
        cgr.position = _this.position;
        cgr.width = _this.width;
        cgr.height = _this.height;

        if (cgr.canvasWidth !== _this.dataWidth || cgr.canvasHeight !== _this.dataHeight) {
          cgr.canvasWidth = _this.dataWidth;
          cgr.canvasHeight = _this.dataHeight;
          cgr.drawCanvas(function(ctx) {
            ctx.fillStyle = 'white';
            ctx.fillRect(0, 0, _this.dataWidth, _this.dataHeight);
          });
        }
      };
      updateGroundRectangle();
      _this.disposers.push((0, _mobx.reaction)(function() {
        return {
          position: [].concat((0, _toConsumableArray3.default)(_this.position)),
          width: _this.width,
          height: _this.height,
          dataWidth: _this.dataWidth,
          dataHeight: _this.dataHeight
        };
      }, updateGroundRectangle));

      _this._imageData = undefined;
      _this._colorPalette = new Uint8ClampedArray(256 * 4);
      _this._colorPalette.fill(255);
      _this.disposers.push(function() {
        _this._imageData = undefined;
        _this._colorPalette = undefined;
      });

      var updateColorPalette = function updateColorPalette() {
        getColorPalette(_this.gradient, _this._colorPalette);
      };
      updateColorPalette();
      _this.disposers.push((0, _mobx.reaction)(function() {
        return {
          gradient: [].concat((0, _toConsumableArray3.default)(_this.gradient))
        };
      }, updateColorPalette));
      return _this;
    }

    /**
     * 设置网格数据 <br/>
     * gridData[0] 西北角 <br/>
     * gridData[dataWidth-1] 东北角 <br/>
     * gridData[(dataHeight-1)*dataWidth] 西南角 <br/>
     * gridData[dataHeight*dataWidth-1] 东南角 <br/>
     * @param {number[]} gridData 网格数据数组，数组长度为width*height
     */

    (0, _createClass3.default)(HeatMap, [{
      key: 'setGridData',
      value: function setGridData(gridData) {
        var _this2 = this;

        var data = gridData;
        if (data && data.length && data.length === this.dataWidth * this.dataHeight) {
          if (!this._imageData || this._imageData.width !== this.dataWidth || this._imageData.height !==
            this.dataHeight) {
            this._imageData = new ImageData(this.dataWidth, this.dataHeight);
          }

          var valueRange = this.maxValue - this.minValue;
          var color = [255, 255, 255, 255];
          var dataHeight = this.dataHeight;
          var dataWidth = this.dataWidth;
          var imageData = this._imageData.data;
          var minValue = this.minValue;
          var colorPalette = this._colorPalette;

          // 为了性能提升，用eval的方式来替代
          // valueRange
          // getColorFromColorPalette
          // for (let j=0; j<dataHeight; ++j) {
          //     for (let i=0; i<dataWidth; ++i) {
          //         const v = data[j*dataWidth+i];
          //         const ratio = (v - minValue) / valueRange;
          //         const c = getColorFromColorPalette(ratio, colorPalette, color);
          //         if (c) {
          //              const offset = (j*dataWidth+i) * 4;
          //              imageData[offset + 0] = c[0];
          //              imageData[offset + 1] = c[1];
          //              imageData[offset + 2] = c[2];
          //              imageData[offset + 3] = c[3];
          //         }
          //     }
          // }
          if (!setImageDataFunc) {
            var evalString =
              '\n                    for (let j=0; j<dataHeight; ++j) {\n                        for (let i=0; i<dataWidth; ++i) {\n                            const v = data[j*dataWidth+i];\n                            const ratio = (v - minValue) / valueRange;\n                            const c = getColorFromColorPalette(ratio, colorPalette, color);\n                            if (c) {\n                                const offset = (j*dataWidth+i) * 4;\n                                imageData[offset + 0] = c[0];\n                                imageData[offset + 1] = c[1];\n                                imageData[offset + 2] = c[2];\n                                imageData[offset + 3] = c[3];\n                            }\n                        }\n                    }\n                ';
            var evalWrapString =
              '\n                    "use strict";\n                    return (function(data, valueRange, color, dataHeight, dataWidth, imageData, minValue, colorPalette, getColorFromColorPalette){\n                        ' +
              evalString + '\n                    });\n                ';
            setImageDataFunc = Function(evalWrapString)();
          }
          setImageDataFunc(data, valueRange, color, dataHeight, dataWidth, imageData, minValue,
            colorPalette, getColorFromColorPalette);

          var cgr = this._customGroundRectangle;
          cgr.canvasWidth = this.dataWidth;
          cgr.canvasHeight = this.dataHeight;
          cgr.drawCanvas(function(ctx) {
            // 是否有必要？
            // ctx.clearRect(0, 0, this.dataWidth, this.dataHeight);
            ctx.putImageData(_this2._imageData, 0, 0);
          });
        } else {
          // const cgr = this._customGroundRectangle;
          // cgr.drawCanvas(ctx => {
          //     ctx.fillStyle = 'white';
          //     ctx.fillRect(0, 0, this.dataWidth, this.dataHeight);
          // });

          var _cgr = this._customGroundRectangle;
          _cgr.canvasWidth = this.dataWidth;
          _cgr.canvasHeight = this.dataHeight;
          _cgr.drawCanvas(function(ctx) {
            ctx.fillStyle = 'white';
            ctx.fillRect(0, 0, _this2.dataWidth, _this2.dataHeight);
          });
        }
      }

      /**
       * 从外部canvas拷贝图像数据
       * @param {Canvas} canvas 外部canvas
       */

    }, {
      key: 'copyfromOtherCanvas',
      value: function copyfromOtherCanvas(canvas) {
        if (canvas.width !== this.dataWidth || canvas.height !== this.dataHeight) {
          console.warn('请确保canvas尺寸一致！');
          return;
        }
        this._customGroundRectangle && this._customGroundRectangle._texture && this._customGroundRectangle
          ._texture.copyFrom(canvas);
      }
    }, {
      key: 'flyTo',
      value: function flyTo() {
        this._earth.camera.flyTo(this.position, this.width, [0, -Math.PI / 3, 0]);
      }
    }]);
    return HeatMap;
  }(_XbsjCzmObj3.default);

  /**
   * 通过克里金插值算法绘制热力图
   * @param {object} posValues 形式如[[x, y, v], [], ...]  x在0-width范围之内，y在0-height范围之内，v必须大于0
   * @param {number} width 宽度
   * @param {number} height 高度
   * @param {object} krigingOptions 
   * @returns {number[] | undefined} 返回结果，如果为undefined，说明计算出错！
   * @static
   * @memberof Obj.HeatMap
   * @example
   * var gridData = new Array(100*100);
   * gridData.fill(0);
   * const posValues = [[10, 10, 100], [10, 90, 500], [90, 10, 300], [90, 90, 1000]];
   * var gridData = XE.Obj.HeatMap.getGridDataFromKriging(posValues, 100, 100, gridData);
   */

  function getGridDataFromKriging(posValues, width, height, resultGridData) {
    var _ref = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {},
      _ref$model = _ref.model,
      model = _ref$model === undefined ? "exponential" : _ref$model,
      _ref$sigma = _ref.sigma2,
      sigma2 = _ref$sigma === undefined ? 0 : _ref$sigma,
      _ref$alpha = _ref.alpha,
      alpha = _ref$alpha === undefined ? 100 : _ref$alpha;

    var gridData = resultGridData;

    try {
      // TODO(vtxf): posValues 需要去重，否则克里金插值可能报错
      var values = [];
      var xs = [];
      var ys = [];
      posValues.forEach(function(e) {
        xs.push(e[0]);
        ys.push(e[1]);
        values.push(e[2]);
      });

      var variogram = _kriging2.default.train(values, xs, ys, model, sigma2, alpha);

      for (var i = 0; i < width; ++i) {
        for (var j = 0; j < height; ++j) {
          gridData[j * width + i] = _kriging2.default.predict(i, j, variogram);
          if (!isFinite(gridData[j * width + i])) {
            throw new Error('克里金插值计算出错！');
          }
        }
      }

      return gridData;
    } catch (error) {
      console.warn('error: ' + error);
      return undefined;
    }
  }

  /**
   * 网格数据插值
   * @param {*} ratio 0-1之间
   * @param {*} gridData0 第一个gridData数据
   * @param {*} gridData1 第二个gridData数据
   * @param {*} length 数组长度
   * @param {*} resultData 结果数据
   * @returns {number[] | undefined} 返回结果，如果为undefined，说明插值出错！
   * @static
   * @memberof Obj.HeatMap
   * @example
   * var d0 = [10, 20, 30, 40]
   * var d1 = [20, 30, 40, 50];
   * var r = new Array(4); r.fill(0);
   * r = XE.Obj.HeatMap.interpolateGridData(0.4, d0, d1, 4, r);
   */
  function interpolateGridData(ratio, gridData0, gridData1, length, resultData) {
    try {
      if (!resultData) {
        return undefined;
      }

      for (var i = 0; i < length; ++i) {
        resultData[i] = gridData0[i] * (1.0 - ratio) + gridData1[i] * ratio;
      }

      return resultData;
    } catch (error) {
      return undefined;
    }
  }

  HeatMap.getGridDataFromKriging = getGridDataFromKriging;
  HeatMap.interpolateGridData = interpolateGridData;

  HeatMap.defaultOptions = {
    /**
     * @description 位置数组 [经度、纬度、高度]
     * @type {array}
     * @instance
     * @default [0, 0, 0]
     * @memberof Obj.HeatMap
     */
    position: [0, 0, 0],
    /**
     * 宽度
     * @type {number}
     * @instance
     * @default 100
     * @memberof Obj.HeatMap
     */
    width: 100,
    /**
     * 高度
     * @type {number}
     * @instance
     * @default 100
     * @memberof Obj.HeatMap
     */
    height: 100,
    /**
     * @description 原点
     * @type {array}
     * @instance
     * @default [0.5, 0.5]
     * @memberof Obj.HeatMap
     */
    origin: [0.5, 0.5],
    /**
     * @description 旋转角
     * @type {number}
     * @instance
     * @default 0
     * @memberof Obj.HeatMap
     */
    rotation: 0.0,
    /**
     * 显示
     * @type {boolean}
     * @instance
     * @default true
     * @memberof Obj.HeatMap
     */
    show: true,
    /**
     * 调色板，形式如 [[x, y], [x1, y1], ...] x为数字，0-1之间；y表示颜色的字符串形式
     * @type {array}
     * @instance
     * @default [[0, 'green'], [0.2, 'blue'], [0.6, 'yellow'], [1.0, 'red']]
     * @memberof Obj.HeatMap
     * @example
     * xxx.gradient = [[0, 'green'], [0.2, 'blue'], [0.6, 'yellow'], [1.0, 'red']];
     */
    gradient: [
      [0, 'green'],
      [0.2, 'blue'],
      [0.6, 'yellow'],
      [1.0, 'red']
    ],
    /**
     * 网格数据最小值
     * @type {number}
     * @instance
     * @default 0
     * @memberof Obj.HeatMap
     */
    minValue: 0,
    /**
     * 网格数据最大值
     * @type {number}
     * @instance
     * @default 1
     * @memberof Obj.HeatMap
     */
    maxValue: 1,
    /**
     * 网格数据宽度
     * @type {number}
     * @instance
     * @default 100
     * @memberof Obj.HeatMap
     */
    dataWidth: 100,
    /**
     * 网格数据高度
     * @type {number}
     * @instance
     * @default 100
     * @memberof Obj.HeatMap
     */
    dataHeight: 100
  };

  _XbsjObject2.default.registerType(HeatMap, 'HeatMap');

  exports.default = HeatMap;

  /***/
}),
